//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using LargoCommon.Interfaces;
using System;
using System.Collections;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using System.Xml.Serialization;
namespace LargoCommon.Music
{
/// Rhythmical shape.
/// Rhythmical shape represents simplified rhythm of one bar. It is always
/// assigned to certain rhythmical modality (and to rhythmical GSystem).
/// It has also inner characteristics (mobility, tension, ..).
[Serializable]
[XmlRoot]
public class RhythmicShape : BinarySchema, IRhythmic, IModalStruct
{
//// Properties:mean, mobility, tension, jazz,entropy
#region Constructors
/// Initializes a new instance of the RhythmicShape class. Serializable.
public RhythmicShape() {
}
///
/// Initializes a new instance of the RhythmicShape class.
///
/// The given system.
/// Bit array.
public RhythmicShape(GeneralSystem givenSystem, BitArray bitArray)
: base(givenSystem, bitArray) {
Contract.Requires(givenSystem != null);
}
///
/// Initializes a new instance of the RhythmicShape class.
///
/// The given system.
/// Structural code.
public RhythmicShape(GeneralSystem givenSystem, string structuralCode)
: base(givenSystem, structuralCode) {
Contract.Requires(givenSystem != null);
}
///
/// Initializes a new instance of the RhythmicShape class.
///
/// Rhythmic shape.
public RhythmicShape(BinaryStructure shape)
: base(shape) {
Contract.Requires(shape != null);
}
///
/// Initializes a new instance of the RhythmicShape class.
///
/// System order.
/// Rhythmical structure.
public RhythmicShape(byte sysOrder, IGeneralStruct structure)
: base(RhythmicSystem.GetRhythmicSystem(RhythmicDegree.Shape, sysOrder), (string)null) {
Contract.Requires(structure != null);
for (byte e = 0; e < this.GSystem.Order; e++) {
if (structure.IsOn(e)) {
this.On(e);
}
}
this.DetermineLevel();
}
///
/// Initializes a new instance of the RhythmicShape class.
///
/// The given system.
/// Number of structure.
public RhythmicShape(GeneralSystem givenSystem, long number)
: base(givenSystem, number) {
}
#endregion
#region Interface
/// Gets rhythmical system.
/// Property description.
[XmlIgnore]
public RhythmicSystem RhythmicSystem => (RhythmicSystem)this.GSystem;
/// Gets or sets rhythmical modality.
/// Property description.
[XmlIgnore]
public RhythmicModality RhythmicModality { get; set; }
/// Gets or sets previous rhythmical shape.
/// Property description.
[XmlIgnore]
public RhythmicShape PreviousShape { get; set; }
#endregion
#region Static factory methods
///
/// Get NewRhythmicShape.
///
/// The given system.
/// Structural code.
///
/// Returns value.
///
public static RhythmicShape GetNewRhythmicShape(GeneralSystem givenSystem, string structuralCode) {
Contract.Requires(givenSystem != null);
var rs = new RhythmicShape(givenSystem, structuralCode);
rs.DetermineBehavior();
return rs;
}
///
/// Get NewRhythmicShape.
///
/// The given system.
/// Bit array.
///
/// Returns value.
///
public static RhythmicShape GetNewRhythmicShape(GeneralSystem givenSystem, BitArray bitArray) {
Contract.Requires(givenSystem != null);
var rs = new RhythmicShape(givenSystem, bitArray);
rs.DetermineBehavior();
return rs;
}
///
/// Get New RhythmicShape.
///
/// Rhythmic shape.
/// Returns value.
public static RhythmicShape GetNewRhythmicShape(BinaryStructure shape) {
Contract.Requires(shape != null);
var rs = new RhythmicShape(shape);
rs.DetermineBehavior();
return rs;
}
///
/// Get NewRhythmicShape.
///
/// Rhythmical Structure.
/// Returns value.
public static RhythmicShape GetNewRhythmicShape(FiguralStructure structure) {
Contract.Requires(structure != null);
var rs = new RhythmicShape(structure.GSystem.Order, structure);
rs.DetermineBehavior();
return rs;
}
#endregion
#region Public methods
/// Makes a deep copy of the RhythmicShape object.
/// Returns object.
public override object Clone() {
return GetNewRhythmicShape(this.GSystem, this.GetStructuralCode);
}
/// Validity test.
/// Returns value.
public override bool IsEmptyStruct() {
return base.IsEmptyStruct() || this.IsOff(0);
}
/// Evaluate properties of the structure.
public override void DetermineBehavior() {
this.ComputeRhythmicProperties();
}
#endregion
#region Comparison
/// Support sorting according to level and number.
/// Object to be compared.
/// Returns value.
public override int CompareTo(object obj) {
return obj is RhythmicShape rs ? string.Compare(this.ElementSchema, rs.ElementSchema, StringComparison.Ordinal) : 0;
//// This kills the DataGrid
//// throw new ArgumentException("Object is not a RhythmicShape");
}
/// Test of equality.
/// Object to be compared.
/// Returns value.
public override bool Equals(object obj) {
//// check null (this pointer is never null in C# methods)
if (object.ReferenceEquals(obj, null)) {
return false;
}
if (object.ReferenceEquals(this, obj)) {
return true;
}
if (this.GetType() != obj.GetType()) {
return false;
}
return this.CompareTo(obj) == 0;
}
/// Support of comparison.
/// Returns value.
public override int GetHashCode() {
return this.ElementSchema != null ? this.ElementSchema.GetHashCode() : 0;
}
#endregion
#region String representation
/// Returns value.
/// List of figure elements.
public override string ElementString() {
var s = new StringBuilder();
for (byte e = 0; e < this.GSystem.Order; e++) {
s.Append(this.IsOn(e) ? "V" : "-");
}
return s.ToString();
}
/// Short string representation of the object.
/// Returns value.
public string ToShortString() {
var s = new StringBuilder();
s.Append(" " + this.ElementString());
s.Append(" " + this.DistanceSchema);
return s.ToString();
}
/// String representation of the object.
/// Returns value.
public override string ToString() {
var s = new StringBuilder();
s.Append(string.Format(CultureInfo.InvariantCulture, "{0},{1}", base.ToString(), this.ElementString()));
s.Append(",");
s.AppendLine(this.StringOfProperties());
return s.ToString();
}
#endregion
}
}